import sys, uuid, os, time, datetime, re
from math import *
import visit
import logging

WEB2PY_ROOT = request.env.web2py_path

try:
    visit.AddArgument("-nowin")
    visit.Launch()
except Exception:    
    logging.info('Viewer is already launched')

from visit import *

class Show:
    def __init__(self,file,angle1=0.7,angle2=-0.7,isoMin=-0.3,isoMax=0.3,pseMin=-0.5,pseMax=0.5,flag=0,type='Pseudocolor & Isosurface'):
        self.file=file
        self.isoMin=isoMin
        self.isoMax=isoMax
        self.pseMin=pseMin
        self.pseMax=pseMax
        self.angle1=angle1
        self.angle2=angle2
        self.flag=flag
        
        # raise HTTP(200,str(dir(visit)))
        
        ReplaceDatabase(self.file)
        #splatting
        if type=='VolumeSplatting':
            AddPlot("Volume", "scalars_t0", 1, 1)
            VolumeAtts = VolumeAttributes()
            VolumeAtts.legendFlag = 1
            VolumeAtts.lightingFlag = 1
            VolumeAtts.colorControlPoints.GetControlPoints(0).colors = (0, 0, 255, 0)
            VolumeAtts.colorControlPoints.GetControlPoints(0).position = 0
            VolumeAtts.colorControlPoints.GetControlPoints(1).colors = (0, 255, 255, 0)
            VolumeAtts.colorControlPoints.GetControlPoints(1).position = 0.25
            VolumeAtts.colorControlPoints.GetControlPoints(2).colors = (0, 255, 0, 0)
            VolumeAtts.colorControlPoints.GetControlPoints(2).position = 0.5
            VolumeAtts.colorControlPoints.GetControlPoints(3).colors = (255, 255, 0, 0)
            VolumeAtts.colorControlPoints.GetControlPoints(3).position = 0.75
            VolumeAtts.colorControlPoints.GetControlPoints(4).colors = (255, 0, 0, 0)
            VolumeAtts.colorControlPoints.GetControlPoints(4).position = 1
            VolumeAtts.colorControlPoints.smoothingFlag = 1
            VolumeAtts.colorControlPoints.equalSpacingFlag = 0
            VolumeAtts.colorControlPoints.discreteFlag = 0
            VolumeAtts.colorControlPoints.externalFlag = 0
            VolumeAtts.opacityAttenuation = 1
            VolumeAtts.freeformFlag = 1
#controlPoints does not contain any GaussianControlPoint objects.
            VolumeAtts.resampleTarget = 50000
            VolumeAtts.opacityVariable = "default"
            VolumeAtts.freeformOpacity = (255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 23, 23, 23, 15, 11, 11, 15, 15, 15, 11, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255)
            VolumeAtts.useColorVarMin = 0
            VolumeAtts.colorVarMin = 0
            VolumeAtts.useColorVarMax = 0
            VolumeAtts.colorVarMax = 0
            VolumeAtts.useOpacityVarMin = 0
            VolumeAtts.opacityVarMin = 0
            VolumeAtts.useOpacityVarMax = 0
            VolumeAtts.opacityVarMax = 0
            VolumeAtts.smoothData = 0
            VolumeAtts.samplesPerRay = 500
            VolumeAtts.rendererType = VolumeAtts.Splatting  # Splatting, Texture3D, RayCasting, RayCastingIntegration, SLIVR
            VolumeAtts.gradientType = VolumeAtts.SobelOperator  # CenteredDifferences, SobelOperator
            VolumeAtts.num3DSlices = 200
            VolumeAtts.scaling = VolumeAtts.Linear  # Linear, Log10, Skew
            VolumeAtts.skewFactor = 1
            VolumeAtts.sampling = VolumeAtts.Rasterization  # KernelBased, Rasterization
            VolumeAtts.rendererSamples = 3
            SetPlotOptions(VolumeAtts)

        if type == 'VolumeRayCasting':
            AddPlot("Volume", "scalars_t0",1,1)
            VolumeAtts = VolumeAttributes()
            VolumeAtts.legendFlag = 1
            VolumeAtts.lightingFlag = 1
            VolumeAtts.colorControlPoints.GetControlPoints(0).colors = (0, 0, 255, 0)
            VolumeAtts.colorControlPoints.GetControlPoints(0).position = 0
            VolumeAtts.colorControlPoints.GetControlPoints(1).colors = (0, 255, 255, 0)
            VolumeAtts.colorControlPoints.GetControlPoints(1).position = 0.25
            VolumeAtts.colorControlPoints.GetControlPoints(2).colors = (0, 255, 0, 0)
            VolumeAtts.colorControlPoints.GetControlPoints(2).position = 0.5
            VolumeAtts.colorControlPoints.GetControlPoints(3).colors = (255, 255, 0, 0)
            VolumeAtts.colorControlPoints.GetControlPoints(3).position = 0.75
            VolumeAtts.colorControlPoints.GetControlPoints(4).colors = (255, 0, 0, 0)
            VolumeAtts.colorControlPoints.GetControlPoints(4).position = 1
            VolumeAtts.colorControlPoints.smoothingFlag = 1
            VolumeAtts.colorControlPoints.equalSpacingFlag = 0
            VolumeAtts.colorControlPoints.discreteFlag = 0
            VolumeAtts.colorControlPoints.externalFlag = 0
            VolumeAtts.opacityAttenuation = 1
            VolumeAtts.freeformFlag = 1
#controlPoints does not contain any GaussianControlPoint objects.
            VolumeAtts.resampleTarget = 50000
            VolumeAtts.opacityVariable = "default"
            VolumeAtts.freeformOpacity =  (255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 7, 11, 15, 19, 19, 23, 23, 23, 23, 23, 23, 23, 19, 19, 19, 19, 15, 15, 11, 11, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255)
            VolumeAtts.useColorVarMin = 0
            VolumeAtts.colorVarMin = 0
            VolumeAtts.useColorVarMax = 0
            VolumeAtts.colorVarMax = 0
            VolumeAtts.useOpacityVarMin = 0
            VolumeAtts.opacityVarMin = 0
            VolumeAtts.useOpacityVarMax = 0
            VolumeAtts.opacityVarMax = 0
            VolumeAtts.smoothData = 0
            VolumeAtts.samplesPerRay = 1000
            VolumeAtts.rendererType = VolumeAtts.RayCasting  # Splatting, Texture3D, RayCasting, RayCastingIntegration, SLIVR
            VolumeAtts.gradientType = VolumeAtts.SobelOperator  # CenteredDifferences, SobelOperator
            VolumeAtts.num3DSlices = 200
            VolumeAtts.scaling = VolumeAtts.Linear  # Linear, Log10, Skew
            VolumeAtts.skewFactor = 1
            VolumeAtts.sampling = VolumeAtts.Rasterization  # KernelBased, Rasterization
            VolumeAtts.rendererSamples = 3
            SetPlotOptions(VolumeAtts) 

        if type=='Pseudocolor & Isosurface':
            AddPlot("Pseudocolor", "scalars_t0")
            AddOperator("Isosurface", 1)
            
        #set isosurface attributes
            isoAttributes = IsosurfaceAttributes()
            isoAttributes.min = self.isoMin
            isoAttributes.minFlag = True
            isoAttributes.max = self.isoMax
            isoAttributes.maxFlag = True
            isoAttributes.variable = "scalars_t0"
            SetOperatorOptions(isoAttributes)
            
        #set pseudocolor attributes
            pseAttributes = PseudocolorAttributes()
            pseAttributes.min = self.pseMin
            pseAttributes.minFlag = True
            pseAttributes.max = self.pseMax
            pseAttributes.maxFlag = True
            pseAttributes.opacity = 0.5
            pseAttributes.colorTableName = "contoured"
            pseAttributes.pointSize = 2
            SetPlotOptions(pseAttributes)

        DrawPlots()

              
    def image(self):
        #set angle of view
        v = GetView3D()
        v.viewNormal = (-sin(self.angle1),-sin(self.angle2)*cos(self.angle1),-cos(self.angle2)*cos(self.angle1))
        v.viewUp = (0,-cos(self.angle2),sin(self.angle2))
        SetView3D(v)
        
        #set annotation
        a=AnnotationAttributes()
        a.axesFlag=False
        a.triadFlag=False
        a.userInfoFlag=False
        a.databaseInfoFlag=False
        a.legendInfoFlag=False
        #if self.flag&1:
        if self.flag:
            a.backgroundColor=(0,0,0,255)
            a.foregroundColor=(255,255,255,255)
        SetAnnotationAttributes(a)
        
        #set save option
        s = SaveWindowAttributes()
        tempID=uuid.uuid4()
        s.fileName = str(tempID)
        s.format = s.PNG
        s.outputToCurrentDirectory = False
        s.outputDirectory = os.path.join(request.folder,'uploads')
        SetSaveWindowAttributes(s)
        #ID='home/zhong/Documents/'+str(tempID)+'0000.jpeg'
        ID=str(tempID)+'0000.png'
    
        SaveWindow()
        ResetView()
        DeleteActivePlots()
        DeleteAllPlots()
        ClearWindow()
        return ID

def visualize(id=None):
    if id is None:
        raise Exception('id is required')
    row = db(db.visualizedfile.id == int(id)).select().first()
    if row is None:
        raise Exception('no row found with id %s.' % id)
    processedfile = row.processedfile
    #if row.status!=QUEUED or processedfile!=COMPLETED:
    #    return
    try:
        logging.info('processing visualizedfile #%s.' % id)
        row.update_record(status = PROCESSING)
        db.commit()
        vtkfile = processedfile.vtkfile
        angles = row.viewangle
        if angles == '|None|None|':
            angle1 = 0.0
            angle2 = 0.0
        else:
            angles = angles.split('|')
            angle1 = float(angles[1])
            angle2 = float(angles[2])
        pngfile = Show(file=locate_file(vtkfile),
                       angle1=angle1,
                       angle2=angle2,
                       flag=row.background_color,
                       type=row.plott).image()
        logging.info('done!')
        row.update_record(pngfile=db.visualizedfile.pngfile.store(open(locate_file(pngfile),'rb'), ".png"),
                          status=COMPLETED,
                          completed_processing_on=datetime.datetime.today())
        db.commit()
        os.unlink(locate_file(pngfile))
    except Exception,e:
        row.update_record(status = FAILED)
        db.commit()
        logging.error('failed visualizedfile #%s: %s' % (id, e))


id = int(sys.argv[-1])
visualize(id)
